package com.iot.gateway.tsl.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.iot.gateway.tsl.mapper.TslServiceAttrMapper;
import com.iot.gateway.tsl.mapper.TslServiceMapper;
import com.iot.gateway.tsl.model.TslServiceAttrEntity;
import com.iot.gateway.tsl.model.TslServiceEntity;
import com.iot.gateway.tsl.qo.ServiceQo;
import com.iot.gateway.tsl.service.TslServiceService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 物模型管理 - 服务管理实现
 *
 * 对应 TSL JSON 中 commands[] 节点，包含 pid, name, desc, required, callType,
 * inputData, outputData, method 以及自定义扩展字段
 *
 * @author guoxinyu
 * @create 2025/5/27 17:50
 */
@Service
public class TslServiceServiceImpl implements TslServiceService {

    private final TslServiceMapper serviceMapper;
    private final TslServiceAttrMapper attrMapper;

    public TslServiceServiceImpl(TslServiceMapper serviceMapper,
                                 TslServiceAttrMapper attrMapper) {
        this.serviceMapper = serviceMapper;
        this.attrMapper = attrMapper;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addService(String deviceId, ServiceQo serviceQo) {
        // 1. 插入固定字段
        TslServiceEntity entity = new TslServiceEntity();
        entity.setServiceId(Optional.ofNullable(serviceQo.getId())
                .filter(id -> !id.isEmpty())
                .orElse(UUID.randomUUID().toString()));
        entity.setDeviceId(deviceId);
        entity.setName(serviceQo.getName());
        entity.setDescription(serviceQo.getDesc());
        entity.setRequired(Boolean.TRUE.equals(serviceQo.getRequired()));
        entity.setCallType(serviceQo.getCallType());
        // JSON 列：inputData/outputData
        entity.setInputData(serviceQo.getInputData());
        entity.setOutputData(serviceQo.getOutputData());
        entity.setMethod(serviceQo.getMethod());
        serviceMapper.insert(entity);

        // 2. 插入动态扩展字段
        if (serviceQo.getCustomFields() != null) {
            List<TslServiceAttrEntity> attrs = serviceQo.getCustomFields().entrySet().stream()
                    .map(e -> {
                        TslServiceAttrEntity a = new TslServiceAttrEntity();
                        a.setServiceId(entity.getServiceId());
                        a.setAttrKey(e.getKey());
                        a.setAttrValue(String.valueOf(e.getValue()));
                        return a;
                    })
                    .collect(Collectors.toList());
            attrs.forEach(attrMapper::insert);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateService(String deviceId, ServiceQo serviceQo) {
        // 1. 更新固定字段
        TslServiceEntity entity = new TslServiceEntity();
        entity.setServiceId(serviceQo.getId());
        entity.setDeviceId(deviceId);
        entity.setName(serviceQo.getName());
        entity.setDescription(serviceQo.getDesc());
        entity.setRequired(Boolean.TRUE.equals(serviceQo.getRequired()));
        entity.setCallType(serviceQo.getCallType());
        entity.setInputData(serviceQo.getInputData());
        entity.setOutputData(serviceQo.getOutputData());
        entity.setMethod(serviceQo.getMethod());
        serviceMapper.updateById(entity);

        // 2. 重建动态扩展字段：先删后插
        attrMapper.delete(new LambdaQueryWrapper<TslServiceAttrEntity>()
                .eq(TslServiceAttrEntity::getServiceId, serviceQo.getId()));

        if (serviceQo.getCustomFields() != null) {
            serviceQo.getCustomFields().forEach((k, v) -> {
                TslServiceAttrEntity a = new TslServiceAttrEntity();
                a.setServiceId(serviceQo.getId());
                a.setAttrKey(k);
                a.setAttrValue(String.valueOf(v));
                attrMapper.insert(a);
            });
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteService(String deviceId, String serviceId) {
        // 删除动态扩展字段
        attrMapper.delete(new LambdaQueryWrapper<TslServiceAttrEntity>()
                .eq(TslServiceAttrEntity::getServiceId, serviceId));
        // 删除固定字段
        serviceMapper.deleteById(serviceId);
    }

    @Override
    public List<ServiceQo> getServices(String deviceId) {
        // 1. 查询固定字段
        List<TslServiceEntity> entities = serviceMapper.selectList(
                new LambdaQueryWrapper<TslServiceEntity>()
                        .eq(TslServiceEntity::getDeviceId, deviceId)
        );

        // 2. 批量查询扩展字段
        List<String> ids = entities.stream()
                .map(TslServiceEntity::getServiceId)
                .collect(Collectors.toList());
        List<TslServiceAttrEntity> allAttrs = attrMapper.selectList(
                new LambdaQueryWrapper<TslServiceAttrEntity>()
                        .in(TslServiceAttrEntity::getServiceId, ids)
        );
        Map<String, List<TslServiceAttrEntity>> grouped = allAttrs.stream()
                .collect(Collectors.groupingBy(TslServiceAttrEntity::getServiceId));

        // 3. 组装 DTO
        return entities.stream().map(e -> {
            ServiceQo qo = new ServiceQo();
            qo.setId(e.getServiceId());
            qo.setName(e.getName());
            qo.setDesc(e.getDescription());
            qo.setRequired(e.getRequired());
            qo.setCallType(e.getCallType());
            qo.setInputData(e.getInputData());
            qo.setOutputData(e.getOutputData());
            qo.setMethod(e.getMethod());

            Map<String, Object> custom = new HashMap<>();
            grouped.getOrDefault(e.getServiceId(), Collections.emptyList())
                    .forEach(a -> custom.put(a.getAttrKey(), a.getAttrValue()));
            qo.setCustomFields(custom);

            return qo;
        }).collect(Collectors.toList());
    }
}
